#define PACKED __attribute__((packed))

/*
 * Basic types
 */
typedef uint32 Elf32_Addr;
typedef uint32 Elf32_Off;
typedef uint16 Elf32_Section;
typedef uint16 Elf32_Versym;
typedef ubyte Elf_Byte;
typedef uint16 Elf32_Half;
typedef int32 Elf32_Sword;
typedef uint32 Elf32_Word;
typedef int64 Elf32_Sxword;
typedef uint64 Elf32_Xword;

/*
 * ELF header
 */
#define EI_NIDENT 16
typedef struct {
    ubyte e_ident[EI_NIDENT];
    uint16 e_types;
    uint16 e_machine;
    uint32 e_version;
    Elf32_Addr e_entry;
    Elf32_Off e_phoff;
    Elf32_Off e_shoff;
    uint32 e_flags;
    uint16 e_ehsize;
    uint16 e_phentsize;
    uint16 e_phnum;
    uint16 e_shentsize;
    uint16 e_shnum;
    uint16 e_shstrndx;
} PACKED Elf32_Ehdr;

/*
 * Program header
 */
typedef struct {
    uint32 p_type;
    Elf32_Off p_offset;
    Elf32_Addr p_vaddr;
    Elf32_Addr p_paddr;
    uint32 p_filesz;
    uint32 p_memsz;
    uint32 p_flags;
    uint32 p_align;
} PACKED Elf32_Phdr;

#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6

#define PF_NONE 0
#define PF_X 1
#define PF_W 2
#define PF_R 4